﻿using System.Linq;

namespace StepsManagerLibrary
{
    /// <summary>
    /// Manages mutliple steps while a step can be whatever class you want
    /// </summary>
    /// <typeparam name="T">Class of the Step</typeparam>
    public class StepManager<T> : BaseStepManager<T> where T : class
    {
        #region Members of IStepManager<T>

        #region Navigation

        /// <summary>
        /// Go to the first step of the collection
        /// </summary>
        /// <returns>
        /// Return the first step object or null if not accessible
        /// </returns>
        public override bool GoToFirst()
        {
            // To move from a step to another step we need the Manager to have
            // steps and not currently moving to another step
            if (CanDoAMoveOperation())
            {
                CurrentStep = _steps.First();
                return true;
            }

            // If the move is not authorized, return null
            return false;
        }

        /// <summary>
        /// Go to the last step of the collection
        /// </summary>
        /// <returns>Return the last Step</returns>
        public override bool GoToLast()
        {
            if (CanDoAMoveOperation())
            {
                CurrentStep = _steps.Last();
                return false;
            }

            // If the move is not authorized, return null
            return true;
        }

        /// <summary>
        /// Go to the previous step of the collection
        /// </summary>
        /// <returns>Previous step of the collection</returns>
        public override bool GoToPrevious()
        {
            if (CanDoAMoveOperation())
            {
                int pos = _steps.IndexOf(_currentStep);

                if (pos > 0)
                    --pos;

                CurrentStep = _steps[pos];

                return true;
            }

            return false;
        }

        /// <summary>
        /// Go to the next step of the collection
        /// </summary>
        /// <returns>Next step of the collection</returns>
        public override bool GoToNext()
        {
            if (CanDoAMoveOperation())
            {
                int pos = _steps.IndexOf(_currentStep);

                if (pos < _steps.Count - 1)
                    ++pos;

                CurrentStep = _steps[pos];
                return true;
            }

            return false;
        }

        /// <summary>
        /// Go to the step provided by the user
        /// </summary>
        /// <param name="step">Step of the collection</param>
        /// <returns>Move has been successfully performed</returns>
        public override bool GoTo(T step)
        {
            if (CanDoAMoveOperation() && _steps.Contains(step))
            {
                CurrentStep = step;
                return true;
            }

            return false;
        }

        #endregion

        #endregion
    }
}
